using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Diagnostics;
using LeisureCenter.Api;
using LeisureCenter.Forms;
using LeisureCenter.MenuItems;
using LeisureCenter.WebUI;

namespace LeisureCenter.Core
{
    public class LeisureCenterInstance : ApplicationContext, IInstance, IMessageFilter
    {
        private bool updateRequested;

        private ExceptionHandler exceptionHandler;
        private PlayersManager playersManager;
        private Settings settings;
        private CommandsManager commandsManager;
        private BrowserManager browserManager;
        private MenuManager menuManager;
        private UIManager uiManager;
        private WebUserInterfaceManager _webUserInterfaceManager;
        public PlaylistManager playListManager;
        public PluginsManager pluginsManager;
        public IconsManager iconsManager;
        public LibraryManager libraryManager;
        public DatabaseManager databaseManager;

        private MainForm mainForm;
        private OsdForm osdForm;
        //LibraryForm libraryForm;

        public new MainForm MainForm { get { return mainForm; } }

        public OsdForm OsdForm { get { return this.osdForm; } }

        private void libraryForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            PlaylistManager.Clear();
            pluginsManager.UnloadPlugins();

            if (this.updateRequested)
                StartUpdater();

            ExitThread();
        }

        public LeisureCenterInstance()
        {
            Program.LeisureCenterInstance = this;

            this.exceptionHandler = new ExceptionHandler();
            this.playersManager = new PlayersManager();
            this.settings = Settings.LoadSettings();
            this.commandsManager = new CommandsManager();
            this.browserManager = new BrowserManager();
            this.menuManager = new MenuManager();
            this.uiManager = new UIManager();
            this.playListManager = new PlaylistManager();
            this.pluginsManager = new PluginsManager();
            this.iconsManager = new IconsManager();
            this.databaseManager = new DatabaseManager();
            this.libraryManager = new LibraryManager();
            _webUserInterfaceManager = new WebUserInterfaceManager();

            Thread.CurrentThread.Name = "MainThread";

            LoadingForm loadingForm = new LoadingForm();
            loadingForm.Shown += new EventHandler(loadingForm_Shown);
            loadingForm.Show();
            
            /*System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
            Version appVersion = a.GetName().Version;
            string appVersionString = appVersion.ToString();

            if (Properties.Settings.Default.ApplicationVersion != appVersionString)
            {
                Properties.Settings.Default.Upgrade();
                Properties.Settings.Default.ApplicationVersion = appVersionString;
            }*/

            //Application.DoEvents();
        }

        void loadingForm_Shown(object sender, EventArgs e)
        {
            LoadingForm loadingForm = (LoadingForm)sender;

            loadingForm.Shown -= new EventHandler(loadingForm_Shown);

            Application.DoEvents();

            menuManager.RegisterMainMenuItemsProvider("Bookmarks", new FileSystemBookmarksMainMenuItemsProvider());
            menuManager.RegisterMainMenuItemsProvider("Library", new LibraryMainMenuItemsProvider());
            menuManager.RegisterMainMenuItemsProvider("FileSystem", new FileSystemMainMenuItemsProvider());
            menuManager.RegisterMainMenuItemsProvider("RemovableMedias", new RemovableMediasMainMenuItemsProvider());
            menuManager.RegisterMainMenuItemsProvider("Network", new NetworkMainMenuItemsProvider());
            menuManager.RegisterMainMenuItemsProvider("ExternalApplications", new ExternalApplicationsMainMenuItemsProvider());
            menuManager.RegisterMainMenuItemsProvider("Options", new OptionsMainMenuItemsProvider());

            loadingForm.VerboseWithStep(@"Loading icons...");
            iconsManager.Initialize();

            pluginsManager.LoadPlugins(loadingForm);

            mainForm = new MainForm();
            mainForm.FormClosed += new FormClosedEventHandler(libraryForm_FormClosed);

            loadingForm.VerboseWithStep(@"Initializing library...");
            this.libraryManager.Initialize();

            playListManager.Initialize();

            _webUserInterfaceManager.Initialize();

            osdForm = new OsdForm();

            mainForm.Show();
            loadingForm.Hide();
            //libraryForm = new LibraryForm(this);
            //libraryForm.FormClosed += new FormClosedEventHandler(libraryForm_FormClosed);
            //libraryForm.Show();

            Application.AddMessageFilter(this);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                Application.RemoveMessageFilter(this);
                libraryManager.Dispose();
                Settings.SaveSettings();
                Properties.Settings.Default.Save();
            }
            base.Dispose(disposing);
        }

        public static string DataPath
        {
            get { return (new DirectoryInfo(Application.LocalUserAppDataPath)).Parent.FullName; }
        }

        public Settings Settings { get { return settings; } }
        public IconsManager IconsManager { get { return iconsManager; } }

        #region IInstance Membres

        public IPlayersManager PlayersManager { get { return playersManager; } }

        //public IMediaManager MediaManager { get { return mediaManager; } }

        public ICommandsManager CommandsManager { get { return commandsManager; } }

        public IBrowserManager BrowserManager { get { return browserManager; } }

        public IMenuManager MenuManager { get { return menuManager; } }

        public IPlaylistManager PlaylistManager { get { return playListManager; } }

        public ILeisureCenterUIManager UIManager { get { return this.uiManager; } }

        public void HandleException(Exception ex)
        {
            ExceptionHandler.PublishOnMainThread(ex);
        }

        #endregion

        #region IMessageFilter Membres

        private const ushort WM_KEYDOWN = 0x0100;
        private const ushort WM_MOUSEMOVE = 0x0200;
        private const ushort WM_LBUTTONDOWN = 0x0201;
        private const ushort WM_RBUTTONDOWN = 0x0204;
        private const ushort WM_MBUTTONDOWN = 0x0207;

        public bool PreFilterMessage(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_KEYDOWN:
                //case WM_MOUSEMOVE:
                case WM_LBUTTONDOWN:
                case WM_RBUTTONDOWN:
                case WM_MBUTTONDOWN:
                    if (MainForm != null)
                        MainForm.StartIdle();
                    break;
            }
            return false;
        }

        #endregion

        internal void RequestUpdate()
        {
            this.updateRequested = true;
            commandsManager.EnqueueCommand(LeisureCenterCommand.Exit);
        }

        private void StartUpdater()
        {
            string updaterFilename = Path.GetDirectoryName(Application.ExecutablePath) + @"\Update.exe";
            try
            {
                if (Settings.UpdateToTestVersions)
                    Process.Start(updaterFilename, @"/Vall");
                else
                    Process.Start(updaterFilename);
            }
            catch (Win32Exception ex)
            {
                UIManager.MessageBox(string.Format("An error occured trying to start the updater: \"{0}\".", ex.Message), "error", MessageBoxButtons.OK, Color.Red);
            }
        }
    }
}
